<template>
  <!-- 根据 formItem 的 mutable 属性决定显示内容 -->
  <div v-if="isMutable">
    <!-- 全选复选框 -->
    <el-checkbox
      v-if="hasAllOption"
      v-model="checkAll"
      :indeterminate="isIndeterminate"
      @change="handleCheckAllChange"
    >
      全选
    </el-checkbox>
    <!-- 复选框组 -->
    <el-checkbox-group
      v-bind="formItem.props"
      :model-value="modelRef[formItem.key]"
      @change="handleCheckedChange"
    >
      <!-- 动态生成复选框 -->
      <el-checkbox
        v-for="option in options"
        :key="optionValue(option)"
        :value="optionValue(option)"
      >
        {{ optionLabel(option) }}
      </el-checkbox>
    </el-checkbox-group>
  </div>
  <!-- 不可编辑时显示文本 -->
  <span v-else>{{ text }}</span>
</template>
<script setup lang="ts">
import { CheckboxValueType } from 'node_modules/element-plus/es'
import { ref, computed, defineProps, PropType, toRefs, watch } from 'vue'
// 定义组件属性
const props = defineProps({
  // 透传至Form,用户数据
  model: {
    type: Object as PropType<Record<string, any>>,
    default: () => ({})
  },
  // formItem的表单配置
  formItem: {
    type: Object as PropType<{
      key: string;
      mutable?: boolean;
      ext?: {
        isAll?: boolean;
        options: Array<Record<string, any>>;
        resetKeys?: {
          value: string;
          label: string;
        };
      };
      props?: Record<string, any>;
    }>,
    default: () => ({})
  }
})
// 使用 toRefs 解构 props
const { model } = toRefs(props)
const modelRef = model as Ref<Record<string, any>>
// 全选状态
const checkAll = ref<boolean>(false)
// 部分选中状态
const isIndeterminate = ref<boolean>(false)
// 判断是否可编辑
const isMutable = computed(() =>
  props.formItem.mutable === undefined ? true : props.formItem.mutable
)
// 判断是否有全选选项
const hasAllOption = computed(() => props.formItem.ext?.isAll)
// 获取选项列表
const options = computed(() => props.formItem.ext?.options || [])
// 获取选项的值
const optionValue = (option: Record<string, any>) => {
  const resetKeys = props.formItem.ext?.resetKeys
  return resetKeys ? option[resetKeys.value] : option.value
}
// 获取选项的标签
const optionLabel = (option: Record<string, any>) => {
  const resetKeys = props.formItem.ext?.resetKeys
  return resetKeys ? option[resetKeys.label] : option.label
}// 监听值变化
watch(
  () => modelRef.value[props.formItem.key],
  newVal => {
    const len = options.value.length
    const curLen = newVal?.length || 0
    isIndeterminate.value = curLen > 0 && curLen < len
    checkAll.value = curLen === len
  },
  { immediate: true }
)
// 全选操作
const handleCheckAllChange = (value: CheckboxValueType) => {
  if (value) {
    modelRef.value[props.formItem.key] = options.value.map(optionValue)
  } else {
    modelRef.value[props.formItem.key] = []
  }
}
// 单个选项操作
const handleCheckedChange = (value: CheckboxValueType[]) => {
  modelRef.value[props.formItem.key] = value
}
// 获取值
const text = computed(() => {
  const selectedOptions = options.value.filter(option =>
    modelRef.value[props.formItem.key]?.includes(optionValue(option))
  )
  return selectedOptions.map(optionLabel).join('、')
})
</script>
<style lang="scss" scoped>
.el-checkbox-group {
  display: inline-block;
  margin-left: 30px;
}
</style>
